package cqrtplm.util;

import cqrtplm.info.ImageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Component
@Slf4j
public class RTFileUtil {
    /**
     * 从Excel中提取图片（支持.xls和.xlsx）
     * @param excelFile Excel文件路径
     * @return 包含图片文件、坐标和Sheet名的列表
     */
    public Map<String,File> extractImages(MultipartFile excelFile) throws Exception {
        List<ImageInfo> images = new ArrayList<>();
        try (InputStream fis = excelFile.getInputStream();
             Workbook workbook = WorkbookFactory.create(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            String sheetName = sheet.getSheetName();

            XSSFDrawing drawing = ((XSSFSheet) sheet).getDrawingPatriarch();
            if (drawing == null) {
                return null;
            }
            for (XSSFShape shape : drawing.getShapes()) {
                if (shape instanceof XSSFPicture) {
                    XSSFPicture picture = (XSSFPicture) shape;
                    processXSSFPicture(picture, sheetName, images);
                }
            }
        }
        return images.stream().collect(Collectors.toMap(item -> extractFirstRowNumber(item.getCoordinate()), ImageInfo::getImageFile));
    }

    private static String extractFirstRowNumber(String coordinate) {
        // 使用正则表达式匹配 "Row: X" 中的 X (X为第一个数字)
        Pattern pattern = Pattern.compile("Row:\\s*(\\d+)");
        Matcher matcher = pattern.matcher(coordinate);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "";
    }

    // 处理 .xlsx 图片
    private static void processXSSFPicture(XSSFPicture picture, String sheetName, List<ImageInfo> images)
            throws Exception {
        // 获取坐标信息
        ClientAnchor anchor = picture.getClientAnchor();
        String coord = String.format("Sheet: %s, Col: %d-%d, Row: %d-%d",
                                     sheetName,
                                     anchor.getCol1(), anchor.getCol2(),
                                     anchor.getRow1(), anchor.getRow2()
        );

        // 保存图片
        saveImage(picture.getPictureData().getData(), coord, sheetName, images);
    }

    // 保存图片到文件
    private static void saveImage(byte[] data, String coord, String sheetName, List<ImageInfo> images)
            throws Exception {
        String extension = getImageExtension(data);
        String fileName = String.format("image_%s_%d.%s",
                                        sheetName,
                                        System.currentTimeMillis(),
                                        extension
        );

        try (java.io.FileOutputStream fos = new java.io.FileOutputStream(fileName)) {
            fos.write(data);
        }

        images.add(new ImageInfo(new File(fileName), coord, sheetName));
    }

    // 根据文件头判断图片类型
    private static String getImageExtension(byte[] data) {
        if (data.length >= 4) {
            // PNG: 89 50 4E 47
            if (data[0] == (byte)0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) {
                return "png";
            }
            // JPEG: FF D8 FF
            if (data[0] == (byte)0xFF && data[1] == (byte)0xD8 && data[2] == (byte)0xFF) {
                return "jpg";
            }
        }
        return "dat";
    }


    public static void processBase64ToFile(String base64, String filePath,File file){

        byte[] buffer;
        try {
            BASE64Decoder base64Decoder = new BASE64Decoder();
            buffer = base64Decoder.decodeBuffer(base64);
            FileOutputStream out = new FileOutputStream(filePath);
            out.write(buffer);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("TAG 异常信息:{}", e.getMessage());
        }

    }

    public static void uploadFileToFtp(String server, int port, String user, String password,
                                  String localFilePath, String remoteFilePath) {
        FTPClient ftpClient = new FTPClient();

        try {
            ftpClient.connect(server, port);
            boolean success = ftpClient.login(user, password);

            if (!success) {
                log.info("登录 FTP 失败！");
                return;
            }

            ftpClient.enterLocalPassiveMode(); // 使用被动模式
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 设置为二进制文件

            try (InputStream inputStream = new FileInputStream(localFilePath)) {
                boolean done = ftpClient.storeFile(remoteFilePath, inputStream);
                if (done) {
                    log.info("文件上传成功！");
                } else {
                    log.info("文件上传失败！");
                }
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
